home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- X-UNIX-From: mjr@decuac.DEC.COM
- subject: v15i104: capabilities database routines (lifted from BSD printcap code)
- from: mjr@decuac.DEC.COM (Marcus J. Ranum)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 104
- Submitted-by: mjr@decuac.DEC.COM (Marcus J. Ranum)
- Archive-name: caplib/part01
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: caplib.3 caplib.c
- # Wrapped by mjr@hussar.dco.dec.com on Wed Nov 28 22:14:23 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f caplib.3 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"caplib.3\"
- else
- echo shar: Extracting \"caplib.3\" \(4168 characters\)
- sed "s/^X//" >caplib.3 <<'END_OF_caplib.3'
- X.\" Copyright (c) 1980 The Regents of the University of California.
- X.\" All rights reserved.
- X.\"
- X.\" Redistribution and use in source and binary forms are permitted provided
- X.\" that: (1) source distributions retain this entire copyright notice and
- X.\" comment, and (2) distributions including binaries display the following
- X.\" acknowledgement: ``This product includes software developed by the
- X.\" University of California, Berkeley and its contributors'' in the
- X.\" documentation or other materials provided with the distribution and in
- X.\" all advertising materials mentioning features or use of this software.
- X.\" Neither the name of the University nor the names of its contributors may
- X.\" be used to endorse or promote products derived from this software without
- X.\" specific prior written permission.
- X.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- X.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- X.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X.\"
- X.\" @(#)termcap.3 6.5 (Berkeley) 6/23/90
- X.\"
- X.\" modified to reflect caplib changes by Marcus Ranum, DEC, 1990
- X.\" mjr@decuac.dec.com
- X.\"
- X.TH CAPLIB 3 "Dec 1, 1990"
- X.UC 4
- X.SH NAME
- Xcapgetent, capgetnum, capgetflag, capgetstr \- capabilities database routines.
- X.SH SYNOPSIS
- X.nf
- X.PP
- X.B capgetent(capfile, name, capbuf, capbufsiz)
- X.B char *capfile, *name, *capbuf;
- X.B int capbufsiz;
- X.PP
- X.B capgetnum(capbuf, id)
- X.B char *capbuf, *id;
- X.PP
- X.B capgetflag(capbuf,id)
- X.B char *capbuf, *id;
- X.PP
- X.B char *
- X.B capgetstr(capbuf, id, area, asizep)
- X.B char *capbuf, *id, **area;
- X.B int *asizep;
- X.PP
- X.B capgetnext(fp, capbuf, capbufsiz)
- X.B FILE *fp;
- X.B char *capbuf;
- X.B int capbufsiz;
- X.fi
- X.SH DESCRIPTION
- XThese functions extract and use capabilities from a terminal capability-style
- Xdata base, the format of which is described in
- X.IR termcap (5).
- X.PP
- X.I Capgetent
- Xextracts the entry for the capability from the file named
- X.I capfile
- Xand the entry
- X.I name
- Xinto the buffer at
- X.I capbuf.
- X.I Capbuf
- Xis assumed to be at least of size capbufsiz
- Xand may be passed to subsequent calls to
- X.I capgetnum,
- X.I capgetflag,
- Xand
- X.I capgetstr.
- X.I Capgetent
- Xreturns \-1 if the
- Xdata base file could be opened,
- X0 if the capability name given does not have an entry,
- X2 if the buffer is not sufficiently large,
- Xand 1 if all goes well.
- X.I Capgetent
- Xdoes not check for environment variables or user-defined capabilities
- Xfiles, though such searches can easily be performed as a higher level
- Xof software that makes multiple calls to
- X.I capgetent.
- X.PP
- X.I Capgetnum
- Xgets the numeric value of capability
- X.I id,
- Xfrom the capability buffer
- X.I capbuf
- Xreturning \-1 if is not given for the database entry.
- X.I Capgetflag
- Xreturns 1 if the specified capability is present in
- Xthe database's entry, 0 if it is not.
- X.I Capgetstr
- Xreturns the string value of the capability
- X.I id,
- Xfrom the buffer
- X.I capbuf,
- Xplaces it in a second buffer at
- X.I area,
- Xand advances the
- X.I area
- Xpointer. The remaining amount of space in
- X.I area
- Xis stored in
- X.I asizep
- Xand is adjusted as more space is used. If
- X.I asizep
- Xis a null pointer, the size of the buffer is assumed to be infinite. You
- Xare warned. When a call to
- X.I capgetstr
- Xis made initially, the value of the contents of
- X.I asizep
- Xshould accurately reflect the size of the area.
- XIt decodes the abbreviations for this field described in
- X.IR termcap (5).
- X.I Capgetstr
- Xreturns NULL if the capability was not found.
- X.PP
- X.I Capgetnext
- Xreads the next database entry from the FILE pointer
- X.I fp
- Xinto the space provided at
- X.I capbuf
- Xup to a maximum size of
- X.I capbufsiz.
- X1 is returned if the read was succesful, 0 is returned at end-of-file,
- X-1 is returned if the FILE pointer is a null pointer, and 2 is returned
- Xif the space provided was insufficient.
- X.SH FILES
- X.SH LIMITATIONS
- XThe caplib library differs from
- X.I termcap
- Xin that the "tc=" kludge has been removed and size checking has been
- Xadded. Checking environmental variables is not supported as in
- X.I termcap
- Xbut can easily be supported in higher-level code (which is where
- Xit belonged in the first place). No file descriptors are kept open,
- Xnor are there any globals.
- X.DT
- X.SH SEE ALSO
- Xex(1), curses(3), termcap(5)
- END_OF_caplib.3
- if test 4168 -ne `wc -c <caplib.3`; then
- echo shar: \"caplib.3\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f caplib.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"caplib.c\"
- else
- echo shar: Extracting \"caplib.c\" \(6015 characters\)
- sed "s/^X//" >caplib.c <<'END_OF_caplib.c'
- X/*
- X * Copyright (c) 1983 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X/*
- X * From the BSD lpd source, cleaned into a general library by
- X * Marcus J. Ranum, Digital Equipment Corporation. 1990
- X *
- X * I took out the code that handled the multiple tc= entries, as
- X * the manner in which it was implemented was so vile, and nauseating
- X * as to be unmentionable. :) I added buffer-boundary checking everywhere
- X * appropriate, so now you can use more than BUFSIZ worth of information
- X * if that turns you on.
- X */
- X
- X#include <ctype.h>
- X#include <stdio.h>
- X
- X
- X/*
- X * capnamatch deals with name matching. The first field of the
- X * entry is a sequence of names separated by |'s, so we compare
- X * against each such name. The normal : terminator after the last
- X * name (before the first field) stops us.
- X */
- Xstatic int
- Xcapnamatch(tbuf,np)
- Xregister char *tbuf;
- Xchar *np;
- X{
- X register char *p1;
- X
- X if (*tbuf == '#')
- X return(0);
- X for (;;) {
- X for (p1 = np; *p1 && *tbuf == *p1; tbuf++, p1++)
- X continue;
- X
- X if (*p1 == 0 && (*tbuf == '|' || *tbuf == ':' || *tbuf == 0))
- X return(1);
- X
- X while (*tbuf && *tbuf != ':' && *tbuf != '|')
- X tbuf++;
- X
- X if (*tbuf == 0 || *tbuf == ':')
- X return(0);
- X tbuf++;
- X }
- X}
- X
- X
- X
- X
- Xcapgetnext(fp,bp,bsiz)
- XFILE *fp;
- Xregister char *bp;
- Xint bsiz;
- X{
- X register int c;
- X register int skip = 0;
- X char *tbuf;
- X
- X if (fp == NULL)
- X return(-1);
- X
- X tbuf = bp;
- X for (;;) {
- X switch (c = getc(fp)) {
- X case EOF:
- X fp = NULL;
- X return(0);
- X
- X case '\n':
- X if(bp == tbuf) {
- X skip = 0;
- X continue;
- X }
- X if (bp[-1] == '\\') {
- X bp--;
- X continue;
- X }
- X *bp = '\0';
- X return(1);
- X
- X case '#':
- X if (bp == tbuf)
- X skip++;
- X
- X default:
- X if (skip)
- X continue;
- X if (bp >= tbuf + bsiz) {
- X *bp = '\0';
- X return(2);
- X }
- X *bp++ = c;
- X }
- X }
- X}
- X
- X
- X
- X
- Xstatic char *
- Xcapskip(bp)
- Xregister char *bp;
- X{
- X
- X while((*bp != '\0' && *bp != ':') || (*(bp - 1) == '\\' && *bp == ':'))
- X bp++;
- X
- X if(*bp == ':')
- X bp++;
- X
- X return(bp);
- X}
- X
- X
- X
- X
- X
- X/*
- X * Get an entry for entr "name" in buffer bp,
- X * from the cap file. Parse is very rudimentary;
- X * we just notice escaped newlines.
- X */
- Xcapgetent(capfile,name,bp,bsiz)
- Xchar *capfile;
- Xchar *name;
- Xchar *bp;
- Xint bsiz;
- X{
- X register char *cp;
- X register int c;
- X register int i = 0;
- X register int cnt = 0;
- X char *tbuf;
- X FILE *tf = (FILE *)NULL;
- X char *cp2;
- X
- X tbuf = bp;
- X
- X if((tf = fopen(capfile,"r")) == (FILE *)NULL)
- X return(-1);
- X
- X for(;;) {
- X cp = bp;
- X
- X for(;;) {
- X if((c = getc(tf)) == EOF) {
- X (void)fclose(tf);
- X return(0);
- X }
- X
- X if (c == '\n') {
- X if(cp > bp && *(cp - 1) == '\\'){
- X cp--;
- X continue;
- X }
- X break;
- X }
- X
- X if (cp >= bp + bsiz)
- X return(2);
- X
- X *cp++ = c;
- X }
- X *cp = 0;
- X
- X /* The real work for the match. */
- X if(capnamatch(tbuf,name)) {
- X (void)fclose(tf);
- X return(1);
- X }
- X }
- X}
- X
- X
- X
- X
- X
- X/*
- X * Return the (numeric) option id.
- X * Numeric options look like
- X * li#80
- X * i.e. the option string is separated from the numeric value by
- X * a # character. If the option is not found we return -1.
- X * Note that we handle octal numbers beginning with 0.
- X */
- Xcapgetnum(tbuf,id)
- Xchar *tbuf;
- Xchar *id;
- X{
- X register int i, base;
- X register char *bp = tbuf;
- X
- X for (;;) {
- X bp = capskip(bp);
- X if(*bp == 0)
- X return(-1);
- X
- X if(*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
- X bp++;
- X if(*bp == '@')
- X return(-1);
- X
- X if(*bp != '#')
- X continue;
- X bp++;
- X base = 10;
- X if (*bp == '0')
- X base = 8;
- X i = 0;
- X
- X while (isdigit(*bp))
- X i *= base, i += *bp++ - '0';
- X
- X return(i);
- X }
- X }
- X}
- X
- X
- X
- X
- X/*
- X * Handle a flag option.
- X * Flag options are given "naked", i.e. followed by a : or the end
- X * of the buffer. Return 1 if we find the option, or 0 if it is
- X * not given.
- X */
- Xcapgetflag(tbuf,id)
- Xchar *tbuf;
- Xchar *id;
- X{
- X register char *bp = tbuf;
- X
- X for(;;) {
- X bp = capskip(bp);
- X if(!*bp)
- X return (0);
- X
- X if(*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
- X if(!*bp || *bp == ':')
- X return(1);
- X else
- X if(*bp == '@')
- X return(0);
- X }
- X }
- X}
- X
- X
- X
- X
- X/*
- X * capdecode does the grung work to decode the
- X * string capability escapes.
- X */
- Xstatic char *
- Xcapdecode(str,area,asiz)
- Xregister char *str;
- Xchar **area;
- Xint *asiz;
- X{
- X register char *cp;
- X register int c;
- X register char *dp;
- X int i;
- X
- X cp = *area;
- X
- X while((c = *str++) && c != ':') {
- X switch (c) {
- X
- X case '^':
- X c = *str++ & 037;
- X break;
- X
- X case '\\':
- X dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
- X c = *str++;
- Xnextc:
- X if (*dp++ == c) {
- X c = *dp++;
- X break;
- X }
- X dp++;
- X if (*dp)
- X goto nextc;
- X
- X if(isdigit(c)) {
- X c -= '0', i = 2;
- X do {
- X c <<= 3, c |= *str++ - '0';
- X } while(--i && isdigit(*str));
- X }
- X break;
- X }
- X
- X if(asiz != (int *)0 && (*asiz)-- <= 0)
- X return(NULL);
- X
- X *cp++ = c;
- X }
- X *cp++ = 0;
- X str = *area;
- X *area = cp;
- X return(str);
- X}
- X
- X
- X
- X
- X/*
- X * Get a string valued option.
- X * These are given as
- X * cl=^Z
- X * Much decoding is done on the strings, and the strings are
- X * placed in area, which is a ref parameter which is updated.
- X */
- Xchar *
- Xcapgetstr(tbuf,id,area,asiz)
- Xchar *tbuf;
- Xchar *id;
- Xchar **area;
- Xint *asiz;
- X{
- X register char *bp = tbuf;
- X
- X for (;;) {
- X bp = capskip(bp);
- X if (!*bp)
- X return (0);
- X
- X if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
- X continue;
- X
- X if (*bp == '@')
- X return(0);
- X
- X if (*bp != '=')
- X continue;
- X bp++;
- X return(capdecode(bp,area,asiz));
- X }
- X}
- END_OF_caplib.c
- if test 6015 -ne `wc -c <caplib.c`; then
- echo shar: \"caplib.c\" unpacked with wrong size!
- fi
- chmod +x caplib.c
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-